// @ts-ignore
import {createFFmpeg, CreateFFmpegOptions, fetchFile, FFmpeg} from "@ffmpeg/ffmpeg"
import {createUniqueString} from "./index";

export interface ReadPic {
  name: string;
  data: string | Buffer | Blob | File;
}

export interface PicNames {
  pre: string; // 写入文件的前缀
  suffix: string // 写入文件的后缀
}

export interface Imgs {
  pre: string;
  length: number;
}

export class FFmpegUtils {
  private ffmpeg: FFmpeg

  exit() {
    this.ffmpeg.exit()
  }

  async initFFmpeg(options?: CreateFFmpegOptions) {
    this.ffmpeg = createFFmpeg(options)
    if (!this.ffmpeg.isLoaded()) {
      await this.ffmpeg.load()
    }
  }

  private imgs: Imgs[] = []

  async readSomePic(pics: ReadPic[], imgType: string = 'jpg'): Promise<string> {
    const s = createUniqueString();
    for (let i = 0; i < pics.length; i++) {
      const item = pics[i]
      const uint8Array = await fetchFile(item.data);
      const fileName = `${s}.${i + 1}.${imgType}`
      this.ffmpeg.FS('writeFile', fileName, uint8Array)
    }
    this.imgs.push({
      length: pics.length,
      pre: s
    })
    return s;
  }

  unlinkImgs(picsName: PicNames) {
    const find = this.imgs.find(i => i.pre === picsName.pre);
    if (find) {
      this.imgs.splice(this.imgs.findIndex(i => i === find), 1)
      for (let i = 0; i < find.length; i++) {
        this.ffmpeg.FS("unlink", `${find.pre}.${i + 1}.${picsName.suffix}`)
      }
    }
  }

  /**
   * 图片到视频，只会生成mp4格式的视频
   * @param picsName 图片的名称
   * @param perSecond 每秒多少张图片
   * @param size 生成视频的大小
   */
  async picsToVideo(picsName: PicNames, perSecond: number = 30, size: string = '1920:1080'): Promise<string> {
    const videoFileName = 'zhixinPic2Video.mp4'
    const args: string[] = []
    args.push('-r')
    args.push(perSecond + '')
    args.push('-f')
    args.push('image2')
    args.push('-i')
    args.push(`${picsName.pre}.%d.${picsName.suffix}`)
    args.push('-vf')
    args.push('scale=' + size)
    args.push(videoFileName)
    await this.ffmpeg.run(...args)
    const data = this.ffmpeg.FS('readFile', videoFileName)
    return URL.createObjectURL(new Blob([data.buffer], {type: 'video/mp4'}));
  }
}


// npm install @ffmpeg/ffmpeg @ffmpeg/core
